package client;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

import communication.game.CellsPlayed;

import game.Game;
import game.GameObject;
/**
 * Represente la grille d'une partie
 * @author Julien Roch
 * @version 1.0
 */
public class JPanelGrid extends JPanel {
	/**
	 * Serialisation
	 */
	private static final long serialVersionUID = 7811606356099969692L;
	/**
	 * Une cellule de la grille
	 * @author Julien Roch
	 * @version 1.0
	 */
	public class JPanelCell extends JPanel{
		/**
		 * Serialisation
		 */
		private static final long serialVersionUID = -4642398722099491557L;
		private GameObject object;
		private boolean isOrigin = false;
		private boolean colorRedefined = false;
		private Point position;
		private ClientApplication app;
		private Color color = Color.DARK_GRAY;//new Color(255, 102, 00);
		private Game game;
		/**
		 * Constructeur d'une cellule (case)
		 * @param game La partie
		 * @param position La position
		 * @param app L'application client
		 */
		public JPanelCell(Game game, Point position, ClientApplication app) {
			this.position = position;
			this.app = app;
			this.game = game;
			// creation de la notification souris
			this.addMouseListener(new MouseAdapter(){
				public void mouseClicked(MouseEvent e){
					JPanelCell.this.app.internals.playCell(JPanelCell.this.game, JPanelCell.this.position,
							JPanelCell.this.app.internals.getObjectToPlay());
					JPanelCell.this.app.internals.setObjectToPlay(null);
				}
			});
		}

		/**
		 * Dessiner la case
		 * - La couleur est plus claire sur la derniere case cliquee
		 * @Override
		 */
		
		protected void paintComponent(Graphics g) {
			super.paintComponent(g);
			if(isOrigin && !colorRedefined){
				color = color.brighter();
				colorRedefined = true;
			}
				
			g.setColor(this.color);
			if(object!=null){
				object.draw(g, this.getSize(),this);
				// on rajoute l'ombre...
				Image i = Toolkit.getDefaultToolkit().getImage (this.getClass().getResource("/img/shadow.png"));
				g.drawImage(i,0,0,this.getWidth(),this.getHeight(),this);
			}
			
		}
		/**
		 * Renvoie l'objet associe a la case
		 * @return L'objet
		 */
		public GameObject getObject() {
			return object;
		}
		/**
		 * Definit l'objet associe a la case
		 * @param object L'objet
		 */
		public void setObject(GameObject object) {
			this.object = object;
		}
		/**
		 * Indique si il s'agit d'une case d'origine (derniere jouee)
		 * @param isOrigin case d'origine?
		 */
		public void setIsOrigin(boolean isOrigin){
			this.isOrigin = isOrigin;
		}
		/**
		 * Definit la couleur de la case 
		 * @param color la couleur
		 */
		public void setColor(Color color){
			if(color==null)
				throw new NullPointerException();
			this.color = color;
		}
	}
	/**
	 *  Taille cellule
	 */
	public static final int CELL_SIZE = 32;
	// Grille
	private JPanelCell cells[][];
	/**
	 * Initialise la grille
	 * @param g Le jeu
	 * @param app l'application client
	 */
	public JPanelGrid(Game g, ClientApplication app){
		// Dimensions
		Dimension d = g.getDimension();
		this.setPreferredSize(new Dimension(CELL_SIZE*d.width,CELL_SIZE*d.height));
		this.setMinimumSize(new Dimension(CELL_SIZE*d.width,CELL_SIZE*d.height));
		this.setMaximumSize(new Dimension(CELL_SIZE*d.width,CELL_SIZE*d.height));
		this.setSize(CELL_SIZE*d.width,CELL_SIZE*d.height);
		this.setLayout(new GridLayout(d.width,d.height));
		 
		//Ajout des cases dans la grille
		cells = new JPanelCell[d.width][d.height];
		for(int i = 0;i<d.width;i++){
			for(int j=0;j<d.height;j++){
				cells[i][j] = new JPanelCell(g, new Point(i,j),app);
				cells[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
				this.add(cells[i][j]);
			}
		}
		this.repaint();
	}
	/**
	 * Dessine un element (objet) sur une case
	 * @param obj L'objet a dessiner
	 * @param p Les coordonees de la case
	 */
	public void drawElement(GameObject obj, Point p){
		this.cells[p.x][p.y].setBackground(Color.BLACK);
		this.cells[p.x][p.y].setObject(obj);
		this.cells[p.x][p.y].repaint();
		
	}
	/**
	 * Affiche la celule fraichement jouee
	 * @param cellsPlayed Notification d'une cellule jouee
	 */
	public void setPlayedGrid(CellsPlayed cellsPlayed){
		for(GameObject o : cellsPlayed.getObjects()){
			Point p = o.getPoint();
			this.cells[p.x][p.y].setColor(cellsPlayed.getPlayer().getColor());
			this.drawElement(o, p);
		}
		Point origin = cellsPlayed.getOrigin();
		this.cells[origin.x][origin.y].setIsOrigin(true);
	}
	
}
